/*
 * @Author: zi.yang
 * @Date: 2021-10-01 20:54:44
 * @LastEditors: zi.yang
 * @LastEditTime: 2021-10-03 22:17:22
 * @Description: 弹出消息
 * @FilePath: \ziYangPM\src\components\PmPopup\PmMessage\index.js
 */
import Vue from 'vue'
import Message from './Message.vue'

class PcyAlert {
  constructor () {
    this.timerMap = {}
    this.instance = null
    this.instanceList = []
  }

  // 初始化实例
  initInstance () {
    // 创建构造器
    const MessageConstructor = Vue.extend(Message)
    const div = document.createElement('div')
    this.instance = new MessageConstructor({ el: div })
    document.body.appendChild(this.instance.$el)
    this.instanceList.push(this.instance)
  }

  // 计算当前弹出消息的高度
  computedTop () {
    const count = this.instanceList.length
    // 20:上边距 + 51：弹框的高度
    return count * (20 + 51) - 51
  }

  // 获取一个实例
  getInstance (timerKey) {
    return this.instanceList.find(item => item._uid === this.timerMap['timerKey' + timerKey])
  }

  // 移出一个实例
  removeInstance (instance) {
    const index = this.instanceList.findIndex((ins) => ins._uid === instance._uid)
    this.instanceList.splice(index, 1)
  }

  // 刷新 top
  refresh () {
    this.instanceList.forEach((instance, index) => {
      Vue.set(instance.$data, 'top', (index + 1) * (71) - 51)
    })
  }

  // 定时器
  timer (time = 3, onClose = () => {}) {
    Vue.set(this.instance.$data, 'show', true)
    const timerKey = setTimeout(() => {
      clearTimeout(timerKey)
      const instance = this.getInstance(timerKey)
      Vue.set(instance.$data, 'show', false)
      this.removeInstance(instance)
      this.refresh()
      onClose()
      document.querySelector(`[pm_uid="pm-${instance._uid}"]`).remove()
    }, time * 1000)
    this.instance.$el.setAttribute('pm_uid', 'pm-' + this.instance._uid)
    Object.assign(this.timerMap, { ['timerKey' + timerKey]: this.instance._uid })
  }

  // 执行
  run ({ message, variant, time, onClose }) {
    this.initInstance()
    const top = this.computedTop()
    Object.assign(this.instance.$data, { message, variant, top })
    this.timer(time, onClose)
  }

  success (message, time, onClose) {
    this.run({ message, variant: 'success', time, onClose })
  }

  info (message, time, onClose) {
    this.run({ message, variant: 'info', time, onClose })
  }

  warning (message, time, onClose) {
    this.run({ message, variant: 'warning', time, onClose })
  }

  error (message, time, onClose) {
    this.run({ message, variant: 'danger', time, onClose })
  }

  // alias warning
  warn (message, time, onClose) {
    this.warning(message, time, onClose)
  }
}

export default PcyAlert
